class User {
    constructor(name) {
        this.name = name
        // 构造函数方法
        this.show = function () {
            console.log(this.name);
        }
    }

    // 原型方法
    getName() {
        console.log(this.name);
    }
}

let u = new User('bob')
console.log(u);
u.getName()

class User1 {
    constructor(name) {
        this.name = name;
    }

    show() {
        console.log(this.name);
    }
}

// let xj = new User1("向军");
// //不会枚举出show属性
// for (const key in xj) {
//   console.log(key);
// }

function Hd(name) {
    this.name = name;
}

Hd.prototype.show = function () {
    console.log(this.name);
};

let obj = new Hd("后盾人");
for (const key in obj) {
    console.log(key);
}

class User2 {
    // constructor是构造函数，会在类的对象被创建的时候，直接生成.
    constructor(name) {
        this.name = name;
    }

    static create(name) {
        return new User2(name);
    }

    // 静态方法无法被类的子对象访问到
    static fun() {
        // 静态方法无法访问到内部成员变量
        return this.name
    }

    show() {
        return this.name
    }
}

// 静态方法可以直接被类名使用. 和java一样， 静态方法可以直接被类名访问到.

// 静态方法， 无法访问到内部成员变量.
//           也无法被类对象访问到.
const xj = User2.create("ck");
console.log(xj.show())

// 类实例化的对象无法访问类的静态方法
// console.log(xj.fun())

/**
 * 使用Es5中的方法， 去实现static静态变量
 */

let StaticOBj = (function () {
    let conf = {
        MAX_NUM: 150,
        MIN_NUM: 1
    }

    return {
        get(type) {
            return conf[type] ? conf[type] : null
        }
    }
})()


const static = new StaticOBj()
StaticOBj.get('MAX_NUM')

class User4 {
    site = 'shanghai'

    constructor(name) {
        this.name = name
    }

    show() {
        return `${name}is living in ${site}`
    }
}

// for (const item of User4){ // 这里会报错，TypeError: User4 is not iterable， 不是可以枚举的。
//   console.log(item)
// }

// 静态属性
// 静态属性， 即是给类的属性， 不是给类的子对象的属性

class User5 {
    static URL = 'http:shop_ideawang.top'

    constructor(name) {
        this.name = name
    }

    show() {
        console.log(`${this.name} url:${URL}`)
    }

    static fun() {
        console.log('static method ')
    }

    func() {
        return 'hello' + User5.URL
    }
}

console.log(User5.URL)
// 非静态方法， 无法被类名访问到。
// console.log(User5.show('hahah')) 非静态方法不会被访问到

const user5 = new User5('haha')
// user5.URL// 访问会报错

// 用类的对象访问类方法正常
user5.show('this is the name')

// 用类的对象访问静态方法报错
// user5.fun() // 这里会报错！ 不能访问到。

//可以在类的方法中，使用静态属性，然后，在方法中， 可以使用类名.静态属性的方法， 来访问， 这样便于管理，也减少了数据存储空间.
user5.func()

function func(name) {
    this.name = name

    function show() {
        //这里还不能使用this， 因为这个this指的是show方法， 里面还没有this，
        // 这里这样写， 就会有this.name了， 使用的是func方法的name属性.
        console.log(func.bind('this').name + '111')
    }
}

class cal {

    constructor(name) {
        this.name = name
    }

    show() {
        console.log(this.name + '111')
    }
}

console.dir(func)
console.dir(cal)


function foo() {
    let a = 0
    var b = 0
}

foo()
// console.log(a) // a is not defined
// console.log(b)  // b  is not defined


let newObj = {
    name: "kobe",
    age: 42
}

// 这样会报错， newObj不是string类型的变量
// newObj = JSON.parse(newObj)

// 这样就不会提示， 因为JSON类型转成string类型是可以的.
newObj = JSON.stringify(newObj)
console.log(newObj)

newObj = JSON.parse(newObj)
console.log(newObj)




class Com {
  constructor(name) {
    this.name = name;
  }
}